/*
 * MRSink.cpp
 *
 *  Created on: 26 janv. 2010
 *      Author: mdulongpont
 */

/*
 * mp3Sink.cpp
 *
 *  Created on: 20 janv. 2010
 *      Author: mdulongpont
 */

#if (defined(__WIN32__) || defined(_WIN32)) && !defined(_WIN32_WCE)
#include <io.h>
#include <fcntl.h>
#endif

#include "MRSink.h"  //TO CHANGE
#include "GroupsockHelper.hh"
#include "OutputFile.hh"
#include <stdint.h>

MRSink::MRSink(UsageEnvironment& env, unsigned bufferSize): MediaSink(env), fBufferSize(bufferSize) {
	fBuffer = new unsigned char[bufferSize];
	index = 0;
	pthread_mutex_init(&mutexForQueue, NULL);
}

MRSink::~MRSink(){
	delete[] fBuffer;
}

MRSink* MRSink::createNew(UsageEnvironment& env,unsigned bufferSize){
	do {
		return new MRSink(env, bufferSize);
	} while (0);
	return NULL;
}


Boolean MRSink::continuePlaying() {
  if (fSource == NULL) return False;
  fSource->getNextFrame(fBuffer, fBufferSize,afterGettingFrame, this,onSourceClosure, this);
  return True;
}


void MRSink::afterGettingFrame(void* clientData, unsigned frameSize,unsigned /*numTruncatedBytes*/, struct timeval presentationTime,unsigned /*durationInMicroseconds*/){
	MRSink* sink = (MRSink*)clientData;
	sink->afterGettingFrame1(frameSize, presentationTime);

}


void MRSink::addData(void* data, unsigned dataSize,struct timeval presentationTime){
#ifdef TEST_LOSS
	static unsigned const framesPerPacket = 10;
	static unsigned const frameCount = 0;
	static Boolean const packetIsLost;
	if ((frameCount++)%framesPerPacket == 0) {
		packetIsLost = (our_random()%10 == 0); // simulate 10% packet loss #####
	}
	if (!packetIsLost)
#endif
	if (data != NULL) {
		AVPacket *packet = new AVPacket;
		packet->data = (uint8_t *)data;
		packet->size = (int)dataSize;
		packet->stream_index = index;
		pthread_mutex_lock(&mutexForQueue);
		avPackets.push(packet);
		pthread_mutex_unlock(&mutexForQueue);
		index++;
	}
}


void MRSink::afterGettingFrame1(unsigned frameSize,struct timeval presentationTime){
	addData(fBuffer, frameSize, presentationTime);
	this->continuePlaying();
}


AVPacket * MRSink::getNext(){
	if(avPackets.size() != 0){
		AVPacket *packet = avPackets.front();
#ifdef USE_DECODERS
		pthread_mutex_lock(&mutexForQueue);
#endif
		avPackets.pop();
#ifdef USE_DECODERS
		pthread_mutex_lock(&mutexForQueue);
#endif
		return packet;
	}
	else
		return NULL;
}

void MRSink::writePacketsInFile(){
	ofstream fichierOut("AVPACKET_TEST.txt", ios::out | ios::trunc);
		if(!fichierOut.fail()){
			AVPacket *ap = this->getNext();
			do{
				fichierOut << "AVPacket" << "  -  " << ap->size << endl;
				ap = this->getNext();
			}while (ap != NULL);
		}
}


unsigned int MRSink::getQueueSize()
{
	return avPackets.size();
}


